#pragma GCC optimize("Ofast", "unroll-loops")
#include<bits/stdc++.h>
using namespace std; using ll = long long;
#define For(i, j, k) for ( int i = (j) ; i <= (k) ; i++ )
#define Fol(i, j, k) for ( int i = (j) ; i >= (k) ; i-- )
namespace DSU
{
	int fa[1000009], sz[1000009];
	inline void init(int x) { For(i, 1, x) fa[i] = i, sz[i] = 1; }
	inline int fat(int x) { return x == fa[x] ? x : fa[x] = fat(fa[x]); }
	inline bool issame(int x, int y) { return fat(x) == fat(y); }
	inline void union_(int x, int y)
	{
		if ( ( x = fat(x) ) == ( y = fat(y) ) ) return;
		if ( sz[x] > sz[y] ) sz[x] += sz[y], fa[y] = x;
		else                 sz[y] += sz[x], fa[x] = y;
	}
}
int n, sa[1000009], rk[1000009], d[1000009], e[1000009], l, r, k, fx, fy, vis;
vector < int > ban[1000009]; char ans[1000009], nw;
inline void work()
{
	cin >> n, fill(rk + 1, rk + n + 2, 0);
	For(i, 1, n) cin >> sa[i];
	For(i, 1, n) { if ( i != 1 ) cin >> e[i]; cin >> d[i]; }
	For(i, 1, n) { if ( sa[i] >= n || rk[++sa[i]] ) { cout << "-1\n"; return; } rk[sa[i]] = i; }
	For(i, 1, n)
	{
		if ( ~d[i] & 1 ) { cout << "-1\n"; return; } d[i] = ( d[i] + 1 ) >> 1;
		if ( !d[i] || d[i] > min(i, n - i + 1) ) { cout << "-1\n"; return; }
	}
	For(i, 2, n)
	{
		if ( e[i] & 1 ) { cout << "-1\n"; return; } e[i] >>= 1;
		if ( e[i] > min(i - 1, n - i + 1) ) { cout << "-1\n"; return; }
	}
	DSU::init(n), l = 1, r = 0;
	For(i, 1, n)
	{
		k = i > r ? 1 : min(d[l + r - i], r - i + 1);
		while ( 1 <= i - k && i + k <= n && k < d[i] ) DSU::union_(i - k, i + k), k++;
		if ( i + --k > r ) l = i - k, r = i + k;
	}
	l = 1, r = 0;
	For(i, 1, n)
	{
		k = i > r ? 0 : min(e[l + r + 1 - i], r - i + 1);
		while ( 1 <= i - k - 1 && i + k <= n && k < e[i] ) DSU::union_(i - k - 1, i + k), k++;
		if ( i + --k > r ) l = i - k - 1, r = i + k;
	}
	For(i, 1, n) ban[i].clear();
	For(i, 1, n) if ( 1 <= i - d[i] && i + d[i] <= n )
	{
		if ( ( fx = DSU::fat(i - d[i]) ) == ( fy = DSU::fat(i + d[i]) ) ) { cout << "-1\n"; return; }
		ban[fx].push_back(fy), ban[fy].push_back(fx);
	}
	For(i, 2, n) if ( 1 <= i - e[i] - 1 && i + e[i] <= n )
	{
		if ( ( fx = DSU::fat(i - e[i] - 1) ) == ( fy = DSU::fat(i + e[i]) ) ) { cout << "-1\n"; return; }
		ban[fx].push_back(fy), ban[fy].push_back(fx);
	}
	fill(ans + 1, ans + n + 1, 0), ans[DSU::fat(sa[1])] = nw = 'a';
	For(i, 2, n)
	{
		if ( rk[sa[i - 1] + 1] > rk[sa[i] + 1] ) nw++;
		if ( ans[fx = DSU::fat(sa[i])] ) { if ( nw != ans[fx] ) { cout << "-1\n"; return; } continue; }
		vis = 0; for ( int j : ban[fx] ) if ( ans[j] ) vis |= 1 << ( ans[j] - 'a' );
		while ( nw <= 'z' && vis & ( 1 << ( nw - 'a' ) ) ) nw++;
		if ( nw > 'z' ) { cout << "-1\n"; return; } ans[fx] = nw;
	}
	For(i, 1, n) cout << ans[DSU::fat(i)]; cout << '\n';
}
int main()
{
	freopen("string.in", "r", stdin), freopen("string.out", "w", stdout);
	cin.tie(nullptr) -> sync_with_stdio(false);
	int t; cin >> t; while ( t-- ) work(); return 0;
}